﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Globalization;
using System.Xml;
using System.Windows.Forms;
using System.ServiceModel.Syndication;
using System.Web.Script.Serialization;
using System.Net;


namespace SDRRealTimeTradeReader
{

    public partial class MainFormReader : Form
    {
        private readonly DataTable _dataTable = new DataTable("SDR");
        private readonly DataTable _dataTable2 = new DataTable("SDRCLOSE");
        delegate void DictParameterDelegate(IDictionary<String, IDictionary<String, String>> value, String status);
        private readonly HashSet<String> _sdrItemsRepo = new HashSet<String>();

        public MainFormReader()
        {
            InitializeComponent();

            dataGridView1.DataSource = _dataTable;
            dataGridView1.AllowUserToAddRows = false;

            var colItem1 = new DataColumn("Title", Type.GetType("System.String"));
            _dataTable.Columns.Add(colItem1);
            var colItem2 = new DataColumn("Summary", Type.GetType("System.String"));
            _dataTable.Columns.Add(colItem2);
            var colItem3 = new DataColumn("LastUpdatedTime", Type.GetType("System.String"));
            _dataTable.Columns.Add(colItem3);

            dataGridView2.DataSource = _dataTable2;
            var tab2ColItem1 = new DataColumn("Date", Type.GetType("System.String"));
            _dataTable2.Columns.Add(tab2ColItem1);
            var tab2ColItem2 = new DataColumn("Close(Price)", Type.GetType("System.String"));
            _dataTable2.Columns.Add(tab2ColItem2);

            var sdrTimer = new Timer();
            sdrTimer.Tick += TimerTask;
            sdrTimer.Interval = 15000;
            sdrTimer.Start();
             
        }

        static SyndicationFeed WithProxy()
        {
            const string url = "https://kgc0418-tdw-data-0.s3.amazonaws.com/slices/CREDITS_RSS_FEED.rss#-537056707";

            var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);

            // WWB: Use The Default Proxy
            httpWebRequest.Proxy = WebRequest.DefaultWebProxy;

            // WWB: Use The Thread's Credentials (Logged In User's Credentials)
            if (httpWebRequest.Proxy != null)
                httpWebRequest.Proxy.Credentials = CredentialCache.DefaultCredentials;

            using (var httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse())
            {
                using (System.IO.Stream responseStream = httpWebResponse.GetResponseStream())
                {
                    Debug.Assert(responseStream != null, "responseStream != null");
                    using (XmlReader xmlReader = XmlReader.Create(responseStream))
                    {
                        return SyndicationFeed.Load(xmlReader);

                    }
                }
            }
        }

        static SDRTrade JsonWithProxy()
        {
            const string url = "https://www.quandl.com/api/v1/datasets/OFDP/INDEX_MARKIT_CDXNAIG.json?auth_token=dt-cSd65XxbU5sbgcsnR";

            var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);

            // WWB: Use The Default Proxy
            httpWebRequest.Proxy = WebRequest.DefaultWebProxy;

            // WWB: Use The Thread's Credentials (Logged In User's Credentials)
            if (httpWebRequest.Proxy != null)
                httpWebRequest.Proxy.Credentials = CredentialCache.DefaultCredentials;

            using (var httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse())
            {
                using (System.IO.Stream responseStream = httpWebResponse.GetResponseStream())
                {
                    Debug.Assert(responseStream != null, "responseStream != null");

                    var serializer = new JavaScriptSerializer();
                    var sr = new System.IO.StreamReader(responseStream);
                    var jsonObject = serializer.Deserialize<SDRTrade>(sr.ReadToEnd());

                    foreach (Object[] obj in jsonObject.data)
                    {
                        Debug.WriteLine(" CDX trade data " + obj[0] +" = " + obj[1]);                        
                    }
                    return jsonObject;
                }
            }
        }

        public void UpdateTable(IDictionary<String, IDictionary<String, String>> dictDict, String status)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new DictParameterDelegate(UpdateTable), new Object[] { dictDict, status });
                return;
            }

            foreach(IDictionary<String, String> dict in dictDict.Values) {
                DataRow newRow = _dataTable.NewRow();
                newRow["Title"] = dict["Title"];
                newRow["Summary"] = dict["Summary"];
                newRow["LastUpdatedTime"] = dict["LastUpdatedTime"];
                _dataTable.Rows.Add(newRow);                            
            }
            _dataTable.AcceptChanges();
            label2.Text = status;
        }

        private class StateObjClass
        {
            // Used to hold parameters for calls to TimerTask. 
            public int SomeValue;
            public System.Threading.Timer TimerReference;
            public bool TimerCanceled;
        }

        private void TimerTask(object sender, EventArgs e)
        {
            var state = new StateObjClass { TimerCanceled = false, SomeValue = 1 };
            // Use the interlocked class to increment the counter variable.
            System.Threading.Interlocked.Increment(ref state.SomeValue);
            Debug.WriteLine("Launched new thread  " + DateTime.Now.ToString(CultureInfo.InvariantCulture));
            if (state.TimerCanceled)
            // Dispose Requested.
            {
                state.TimerReference.Dispose();
                Debug.WriteLine("Done  " + DateTime.Now.ToString(CultureInfo.InvariantCulture));
            }

            SyndicationFeed syndicationFeed = WithProxy();
            IDictionary<String, String> dict = new Dictionary<string, string>();
            IDictionary<String, IDictionary<String, String>> sdrItems = new Dictionary<String, IDictionary<String, String>>();
            foreach (SyndicationItem feedItem in syndicationFeed.Items)
            {
                String desiminationId = feedItem.Summary.Text.Split(",".ToCharArray())[0];
                dict["Title"] = feedItem.Title.Text;
                dict["Summary"] = feedItem.Summary.Text;
                dict["LastUpdatedTime"] = feedItem.PublishDate.ToString();

                if (!_sdrItemsRepo.Contains(desiminationId))
                {
                    _sdrItemsRepo.Add(desiminationId);
                    if (!sdrItems.ContainsKey(desiminationId))
                        sdrItems.Add(desiminationId, dict);
                }

                Debug.WriteLine("Dessemination Id  " + desiminationId);
            }
            
            UpdateTable(sdrItems, DateTime.Now.ToString(CultureInfo.InvariantCulture));

        }

        private void MainFormReader_Load(object sender, EventArgs e)
        {
            sdrClosing = JsonWithProxy();
            sourceNameLabel.Text = sdrClosing.source_name;
            nameLabel.Text = sdrClosing.name;
            descriptionLabel.Text = sdrClosing.description;
            updatedAtLable.Text = sdrClosing.updated_at;

            foreach (Object[] data in sdrClosing.data)
            {
                DataRow newRow = _dataTable2.NewRow();
                newRow["Date"] = data[0];
                newRow["Close(Price)"] = data[1];
                _dataTable2.Rows.Add(newRow);
            }
            _dataTable2.AcceptChanges();
        }
    }
}
